بسم الله الرحمن الرحیم
فصل 4
مطالعه موردی: طراحی رابط کاربری
این فصل، شامل یک مطالعهی موردی است که در آن تابعهایی طراحی میشوند که با یکدیگر کار میکنند.
در این فصل، پیمانه (ماژول ) turtle که به شما اجازه میدهد تا اشکال گرافیکی ایجاد کنید، معرفی میشود.
به صورت پیشفرض این ماژول در اکثر نسخههای پایتون وجود دارد، اما اگر از pythonAnyWhere استفاده میکنید، ممکن است اینگونه نباشد.
اگر پایتون را روی کامپیوتر خود نصب کرده باشید، شما قادر خواهید بود که مثالهایی که در این فصل آورده میشود را اجرا کنید. در غیر این صورت الان زمان خوبی است که پایتون را نصب کنید.من در این آدرس راهنماییهایی برای انجام این کار نوشتهام.
کدهایی که در این فصل به عنوان مثال آورده میشوند در این آدرس موجودند.
4.1 ماژول turtle
برای اینکه ببینید این ماژول را در کامپیوتر خود دارید، مفسر پایتون (یا هر برنامهی دیگری که برای اجرای پایتون استفاده میکنید) را باز کنید و دو خط زیر را وارد کنید:
>>> import turtle
>>> bob = turtle.Turtle()
با اجرای دو خط بالا، یک پنجرهی جدید باز میشود که در وسط آن یک فلش کوچک که نمایانگر turtle میباشد، وجود دارد. پنجره را ببندید.
یک فایل با نام mypolygon.py ایجاد کنید، و کد زیر را در آن بنویسید:
import turtle
bob = turtle.Turtle()
print(bob)
turtle.mainloop()
ماژول turtle دارای تابعی یه نام Turtle (دقت کنید که نام تابع با T شروع میشود) است که این تابع یک شیء(object) از ماژول turtle ایجاد میکند. در کد بالا ما این شیء را با متغیر bob نگه داشتیم. با چاپ کردن متغیر bob، خروجی زیر نمایش داده میشود:
<turtle.Turtle object at 0x0000000001CB1B38>
خط بالا به این معنی است که bob یک شیء از ماژول turtle است.
تابع mainloop به پنجرهی باز شده میگوید که منتظر کاربر بماند تا کاری انجام دهد، هر چند در این مثال کاربر به جز بستن پنجره کار دیگری انجام نمیدهد.
هنگامی که یک شیء turtle ایجاد میشود، شما میتوانید با فراخوانی تابعی، فلش آن را درمحیط پنجره جابهجا کنید. به عنوان مثال، برای انتقال رو به جلوی فلش از اینگونه عمل میکنیم:
bob.fd(100)
تابع fd، از تابعهای ماژول turtle است که با ایجاد یک شیء از این ماژول به آن شیء اختصاص داده میشود. فراخوانی یک تابع توسط یک شیء مانند درخواست کردن از آن شیء است. به عنوان مثال در اینجا از شیء bob درخواست کردید که رو به جلو حرکت کند.
آرگومان ورودی که به تابع fd داده میشود فاصلهای است که شیء turtle باید حرکت کند، در اینجا bob به اندازهی 100 پیکسل رو به جلو حرکت میکند. اندازهی واقعی این فاصله به اندازهی نمایشگر شما بستگی دارد.
سایر تابعهایی که میتوانید با استفاده از شیء turtle فراخوانی کنید، عبارت اند از: bk، برای حرکت رو به عقب، lt، برای چرخش به چپ و rt برای چرخش به راست. آرگومان ورودی برای تابعهای lt و rt اندازهی زاویهای است که شیء turtle باید بچرخد.
همچنی هر شیء از ماژول turtle، دارای یک pen میباشد که یا روی صفحهاست و در حال کشیدن است، یا از روی صفحه برداشته شده است.
اگر pen روی صفحه باشد، هنگامی که شیء turtle حرکت میکند، با جابهجایی شیء pen یک خط به دنبال آن رسم میکند. تابعهای pu و pd به ترتیب عمل برداشتن و گذاشتن pen روی صفحه را انجام میدهند.
برای رسم یک زاويه قائمه، خطوط زیر را بعد از ایجاد bob و قبل از فراخوانی mainloop در فایل mypolygon.py بنویسید:
bob.fd(100)
bob.lt(90)
bob.fd(100)
حال سعی کنید، با استفاده از برنامهی که ساخته شدهاست، یک مربع ایجاد کنید. تا زمانی که موفق نشدهاید، خواندن ای فصل را ادامه ندهید!
4.2 تکرار ساده
امیدواریم در تلاشی که کردهاید، چیزی شبیه کد زیر نوشته باشید:
bob.fd(100)
bob.lt(90)
bob.fd(100)
bob.lt(90)
bob.fd(100)
bob.lt(90)
bob.fd(100)
ما میتوانیم همین کار را خیلی دقیقتر با استفاده از یک حلقهی for انجام دهیم. مثال زیر را به فایل mypolygon.py اضافه کنید و آن را دوباره اجرا کنید:
for i in range(4):
print(‘Hello!’)
در خروجی باید چیزی شبیه زیر ببینید:
Hello!
Hello!
Hello!
Hello!
بعدا خواهیم دید که این سادهترین استفاده از حلقهی for است. اما همین فعلا برای شما کافی است، تا بتوانید مربع خود را با آن بازنویسی کنید. تا زمانی که مربع خود را با حلقهی for انجام ندادید، ادامه ندهید!
کد زیر یک حلقهی for است که یک مربع رسم میکند:
for i in range(4):
bob.fd(100)
bob.lt(90)
سینتکس حلقهی for شبیه تعریف یک تابع است، یک سرآیند دارد که با : تمام میشود و یک بدنهی تو رفته که شامل هر تعداد خطی از کد است.
عبارت for از این رو حلقه نامیده میشود که بدنهی آن به صورت تکراری، چند بار اجرا میشود. در دو مثالی که در بالا زده شد، بدنهی حلقهی for برای 4 بار اجرا میشود.
آخرین نسخهی کد رسم مربع کمی با نسخهی قبلی آن متفاوت است. در نسخهی جدید شیء turtle پس از اینکه آخرین ضلع مربع را رسم کرد، یک چرخش اضافی نیز انجام میدهد. همچنین در این نسخه شیء turtle پس از اینکه مربع را به صورت کامل رسم کرد، به مکان اولیه برمیگردد و همان جهت اولیه را دارد.
4.3 تمرینها
در زیر یک سری تمرین برای کار با turtle آمده است. این تمرینها علاوه بر اینکه جذاب هستند، یک نکته نیز دارند. در هنگام انجام این تمرینها فکر کنید ببینید هر تمرین چه نکته ای داشت.
(در قسمتهای بعدی حل تمرینهای زیر آمده است، بنابراین تا زمانی که این تمرینها را به صورت کامل انجام نداده اید، آنها را نبینید.)
- تابعی به نام square ایجاد کنید که یک شیء turtle با نام t دریافت کند. این تابع باید با استفاده از turtle یک مربع رسم کند.
در برنامهای شیء bob را به عنوان آرگومان ورودی به تابع square بدهید و برنامه را اجرا کنید.
- پارامتر دیگری به نام length به تابع square اضافه کنید. تابع را به گونهای اصلاح کنید، که اندازهی ضلع مربی که رسم میشود برابر length باشد. برنامهای که نوشتید را نیز به گونهای اصلاح کنید که علاوه بر شیء bob، یک length نیز به تابع square بدهد. سپس برنامه را اجرا کنید.
- یک کپی از تابع square ایجاد کنید و نام آن را به polygon تغییر دهید. تابع polygon را به گونهای اصلاح کنید که علاوه بر دو آرگومان قبلی، یک آرگومان دیگر به نام با نام n دریافت کند و یک n ضلعی منتظم رسم کند.
راهنمایی: اندازهی هر یک از زاوایههای خارجی یک n ضلعی منتظم، برابر است.
- تابعی با نام circle ایجاد کنید که آرگومانهای ورودی t که یک شیء turtle است و r که اندازهی شعاع دایره است را به عنوان ورودی بگیرد و با فراخوانی تابع polygon یک دایرهی تقریبی رسم کند. تابع خود را با مقادیر مختلف r تست کنید.
راهنمایی: اندازهی محیط دایره برابر است.
- یک نسخهی عمومی تر از تابع circle با نام arc ایجاد کنید که علاوه بر آرگومانهای ورودی circle یک آرگومان ورودی دیگر به نام angle نیز دریافت کند. آرگومان angle مشخص میکند که چه کسری از دایره باید رسم شود. واحد angle درجه است، بنابراین اگر angle برابر 360 درجه باشد، تابع arc باید یک دایرهی کامل رسم کند.
4.4کپسول کردن (Encapsulation)
تمرین اول، زا شما میخواد در برنامهای دیگر تابع square را با یک شیء از turtle به عنوان آرگومان ورودی، فراخوانی کنید. پاسخ این تمرین به این صورت است:
def square(t):
for i in range(4):
t.fd(100)
t.lt(90)
square(bob)
درونیترین عبارتها در کد بالا، یعنی fd و lt دو بار تو رفته اند (indent) که نمایانگر این است درون حلقهی for که متعلق به تابع square است، هستند. خط آخر که تورفتگی ندارد، از تعریف تابع square جداست و تابع square را برای اجرا فراخوانی میکند.
با فراخوانی تابع square و آرگومان ورودی bob، درون تابع، t به bob ارجاع خواهد داد. بنابراین t.lt(90) معادل bob.lt(90) است. چرا در تابع square به جای t از bob استفاده نمیکنیم؟! به این دلیل که در اینجا t میتواند نه تنها bob بلکه هر شیء دیگری از ماژول turtle باشد. بنابراین میتوانید یک شیء دیگر از turtle ابجاد کنید، و تابع square را با استفاده از آن فراخوانی کنید:
alice = turtle.Turtle()
square(alice)
قرار دادن تکهای کد در یک تابع کپسوله کردن گفته میشود. یکی از مزیتهای کپسوله کردن کد این است که به بخشی از کد یک نام (نام تابع) میدهیم که مانند نوعی مستندسازی کد است. مزیت دیگر کپسوله کردن امکان استفادهی چندباره از یک کد خاص است. چرا که این کار باعث میشود از کپی کردنهای زیاد جلوگیری شود، و هرگاه میخواهیم از آن کد استفاده کنیم، به راحتی با استفاده از یک فراخونی تابع این کار را نجام میدهیم.
4.5 عمومی سازی(Generalization)
گام بعدی اضافه کردن آرگومان length به تابع square است، کد زیر این کار رانجام میدهد:
def square(t, length):
for i range(4):
t.fd(length)
t.lt(90)
square(bob,100)
اضافه کردن یک آرگومان به یک تابع، عمومیسازی گفته میشود. زیرا این کار باعث میشود تابع بیشتر عمومی باشد. در نسخهی قبلی تابع square، مربع همیشه دارای یک اندازهی ثابت است، در این نسخه ما میتوانیم مربعی با اندازهی دلخواه داشته باشیم.
گام بعدی نیز نوعی عمومیسازی است. به جای رسم کردن مربع، تابع polygon یک چندضلعی منتظم با هر تعدادی ضلع رسم میکند:
def polygon(t, n, length):
angle = 360/n
for i in range(n):
t.fd(length)
t.lt(angle)
polygon(bob, 7, 70)
مثال بالا یک 7 ضلعی منتظم با طول ضلع 70 پیکسل رسم میکند.
اگر از پایتون 2 استفاده میکند، مقدار angle به دلیل انجام تقسیم اعدادصحیح، ممکن است از مقدار واقعی کمتر باشد. یک راه حل ساده استفاده از مقدار اعشاری 360 یعنی 36.0 است: angle = 360.0/n این کار باعث میشود مقدار angle مقدار واقعی خود که ممکن است یک عدد اعشاری باشد، باشد.
وقتی تابعی چند آرگومان ورودی دارد که مقدار آنها باید عدد باشد، ممکن است خود آرگومان یا ترتیب آنها فراموش شود، در این مواقع راه حل ساده برای جلوگیری از ایجاد مشکل، این است که به هنگام فراخوانی تابع، نام آرگومان مورد نظر و مقدار آن را در فراخوانی تابع بنویسیم:
polygon(bob, n = 7, length = 70)
این آرگومانها، آرگومانهای کلیدواژهای نامیده میشوند، زیرا نام آرگومان مورد نظر به عنوان کلیدواژه آورده میشود. این روش قابلیت خوانایی برنامه را افزایش میدهد.
4.6 طراحی رابط کاربری
گام بعدی نوشتن تابع circle است که شعاع r را به عنوان ورودی دریافت میکند. کد زیر یک 50 ضلعی منتظم رسم میکند:
import math
def circle(t, r):
circumference = 2 * math.pi * r
n = 50
length = circumference/n
polygon(t, n, length)
خط اول محیط دایرهای به شعاع r را محسابه میکند. از آن جا که ما از math.pi استفاده میکنیم، باید ماژول math را فراخوانی (import) کنیم. به صورت قراردادی، عبارات import را معمولا در ابتدای برنامه قرار میدهیم.
همچنین n، تعداد تعداد اضلاعی است که میخواهیم با آن دایره تقریبی خود را رسم کنیم. بنابراین اندازهی هر ضلع این چندضلعی برابر است با تقسیم محیط چندضلعی بر تعداد اضلاع آن. بنابراین این تابع یک 50ضلعی منتظم که به تقریبا مانند یک دایره با شعاع r است، رسم میکند.
یکی از محدودیتهای کد بالا، این است که مقدار n ثابت و برابر 50 است که باعث میشود برای دایرههای خیلی بزرگ، اندازهی ضلع چندضلعی مورد نظر خیلی طولانی است، و برای رسم دایرههای کوچک، برای زسم ضلعهای کوچک، اتلاف وقت داریم.
یک راه حل برای این مشکل، عمومیسازی تابع circle است تا به به عنوان ورودی آرگومان n را دریافت کند.
رابط کاربری یک تابع، چگونگی استفاده از آن تابع است. چه پارامترهایی دارد؟ چه کاری انجام میدهد؟ چه مقداری را برمیگرداند؟ یک رابط کاربری "تمیز" نامیده میشود اگر به کاربر اجازه دهد که هر آنچه که میخواهد را انجام دهد بدون اینکه از جزییات خبر داشته باشد.
در این مثال r، مربوط به رابط کاربری است زیرا شعاع دایرهای که میخواهیم رسم کنیم را تعیین میکند. ولی n اینگونه نیست زیرا n مربوط به این است که دایره چگونه رسم شود که نباید دغدغهی کاربر باشد.
به جای اینکه رابط کاربری را درهم بریزیم، بهتر است که یک مقدار مناسب با استفاده از محیط دایره، برای n انتخاب کنیم:
import math
def circle(t, r):
circumference = 2 * math.pi * r
n = int( circumference / 3) + 1
length = circumference/n
polygon(t, n, length)
حال تعداد قطعه(ضلع) هایی که دایرهی مورد نظر با انها ساخته میشود، عددی نزدیک به circumference/3 است،بنابراین اندازهی هر قطعه حدودا 3 است که به اندازهی کافی کوچک است تا دایره به خوبی دیده شود. این اندازه اندازهای مناسب برای هر اندازهای از شعاع دایره است.
4.7 فاکتورگیری مجدد
وقتی تابع circle را نوشتم، در آن تابع میتوانستم از تابع polygon استفاده کنم، زیرا یک چندضلعی با اضلاع زیاد تقریبا یک دایره است. اما تابع arc اینگونه نیست. ما نمیتوانیم از تابع polygon یا تابع circle برای رسم یک کمان (arc) استفاده کنیم.
یک جایگزین این است که یک کپی از تابع polygon برداریم و آن را به تابع arc منتقل کنیم. نتیجه چیزی شبیه کد زیر میشود:
def arc(t, r, angle):
arc_length = 2 * math.pi * r * angle / 360
n = int(arc_length / 3) + 1
step_length = arc_length / n
step_angle = angle / n
for i in range(n):
t.fd(step_length)
t.lt(step_angle)
نیمهی دوم این تابع، شبیه به polygon است، ولی ما بدون تغییر رابط کاربری تابع polygon نمیتوانیم از آن استفاده کنیم. ما میتوانیم تابع polygon را عمومیسازی کنیم تا یک آرگومان ورودی سوم زاویه دریافت کند، ولی در این صورت دیگر نام polygon برای این تابع خیلی مناسب نیست! به جای آن، اجازه دهید تابعی عمومیتر را polyline بنامیم:
def polyline(t, n, length, angle):
for i in range(n):
t.fd(length)
t.lt(angle)
حال میتوانیم توابع polygon و arc را با استفاده از فراخوانی تابع polyline بازنویسی کنیم:
def polygon(t, n, length):
angle = 360.0 / n
polyline(t, n, length, angle)
def arc(t, r, angle):
arc_length = 2 * math.pi * r * angle / 360
n = int(arc_length / 3) + 1
step_length = arc_length / n
step_angle = float(angle) / n
polyline(t, n, step_length, step_angle)
در نهایت میتوانیم تابع circle را با استفاده از تابع arc بازنویسی کنیم:
def circle(t, r):
arc(t, r, 360)
به مجموعه کارهایی که در بالا انجام دادیم-بازنویسی یک برنامه برای بهبود رابط کاربری آن و تسهیل کردن استفادهی دوباره از کد - فاکتورگیری مجدد میگویند. در این مورد، ما دیدیم که کد مشابهی در تابعهای arc و polygon وجود دارد، بنابراین آن را فاکتور گرفتیم و در تابع polyline قرار دادیم.
اگر قبل از نوشتن کدها فکر میکردیم، حتما ابتدا تابع polyline را مینوشتیم و از فاکتورگیری مجدد استفاده نمیکردیم، اما اغلب در ابتدای انجام یک پروژه ممکن است شما نتوانید همهی رابطهای کاربری را تشخیص و اجرا کنید. وقتی شروع به نوشتن کد کنید، مسله را بهتر متوجه میشوید. گاهی اوقات، فاکتورگیری مجدد نشانهای است از اینکه شما چیزی را یاد گرفتید.
4.8 نقشهی توسعه
یک نقشهی توسعه فرایندی است که منجر به نوشتن یک برنامه میشود. فرایندی که ما در این فصل داشتیم کپسوله کردن و عمومیسازی بود. گامهای این فرایند عبارت اند از:
- نوشتن یک برنامهی کوچک که هیچ تابعی در آن تعریف نشده است.
- وقتی برنامهی گام 1 بدون مشکل اجرا شد، یک بخش پیوسته و منطقی آن را تشخیص دهید، آن بخش را کپسولهسازی کنید و در یک تابع مجزا با نامی مناسب بنویسید.
- با دادن آرگومانهای ورودی مناسب به تابع ساختهشده در گام 2، آن را عمومی سازی کنید.
- گامهای 1 تا 3 را آنقدر تکرار کنید تا به مجموعهای از تابعهایی برسید که به خوبی کار میکنند. از کپی کردن و پیست کردن استفاده کنید تا از دوباره نوشتن کد و عیبیابی دوباره آن اجتناب شود.
- به جاهای مختلف کد نگاه کنید، تا بتوانید یک فاکتورگیری مناسب انجام دهید. برای مثال اگر یک قطعه کد مشابه در جاهای مختلف وجود دارد، آن قطع را فاکتور بگیرید و آن را در یک تابع عمومی مجزا بنویسید.
این فرایند اشکالاتی-که بعدا خواهیم دید- نیز دارد، ولی برای زمانی که شما نمیدانید چگونه برنامه را به تابعهای مختلف تقسیم کنید، مناسب است. این رویکرد به شما اجازه میدهد هرچه به جلو میروید طراحی خود را انجام دهید.
4.9 رشتهمستند
یک رشتهمستند توضیحی است که در ابتدای یک تابع نوشته میشود و رابط کاربری تابع مورد نظر را توضیح میدهد.
به عنوان مثال تابع زیر را ببینید:
def polyline(t, n, length, angle):
"""Draws n line segments with the given length and
angle (in degrees) between them. t is a turtle.
"""
for i in range(n):
t.fd(length)
t.lt(angle
به صورت قراردادی همهی رشتهمستندها بین علامت نقل قول 3گانه(triple-quoted) قرار میگیرد که به رشتهی چندخطه معروف است، زیرا نقل قول 3گانه، اجزاه میدهد تا رشتهی بین آن در چند خط نوشته شود.
رشتهمستند خلاصه و کوتاه است، اما شامل اطلاعت ضروری برای کسی که میخواهد از تابع استفاده کند است. رشتهمستند به طور دقیق توضیح میدهد که تابع چهکاری انجام میدهد(بدون وارد شدن به جزییات پیادهسازی تابع). همچنین توضیح میدهد که هر آرگومان ورودی چه تاثیری بر رفتار تابع دارد، و آرگومانهای وردی از چه نوعی هستند.
نوشتن چنین مستنداتی از مهمترین بخشهای طراحی یک رابط کاربری است. یک رابط کاربری خوب، باید به صورت ساده قابل توضیح باشد، اگر توضیح یکی از رابطهای کاربری که طراحی کردید براتان مشکل است، بدان معنی است که باید این رابط کاربری بهبود یابد.
4.10 عیبیابی
یک رابط کاربری شبیه به قراردادی بین تابع و کسی که تابع را فراخوانی میکند، است. کسی که تابع را فراخوانی میکند، میپذیرد که آرگومانهای خاصی را فراهم کند، و تابع نیز میپذیرد که کار خاصی انجام دهد.
برای مثال تابع polyline به 4 آرگومان ورودی نیاز دارد: t باید turtle باشد، n باید یک عدد صحیح باشد، length باید یک عدد مثبت باشد و angle باید یک عدد باشد که کمتر از 360 باشد.
این نیازمندیها پیششرط نامیده میشوند، زیرا انتظار میرود آنها قبل از اجرای تابع، فراهم شده باشند. برعکس، شرایط بعد از اجرای تابع پسشرط نامیده میشوند. پسشرطها شامل تاثیر مورد نظر از تابع(مانند رسم قطعهخطها در مثال این فصل)، و هر تاثیر جانبی(مانند حرکت دادن turtle) میشود.
پیششرط ها جزو مسولیتهایی است که کسی که تابع را فراخوانی میکند باید انجام دهد. اگر یکی از این پیششرطها توسط کسی که تابع را فراخوانی میکند، نقض شود، و تابع به درست کار نکند، عیب از فراخوانندهی تابع است نه از تابع.
اگر پیششرطها رعایت شدند ولی پسشرطها رعایت نشدند، عیب از تابع است. اگر پیششرطها و پسشرطهای شما واضح باشند، میتوانند به فرایند عیبیابی برنامه کمک کنند.
4.11 واژهنامه
تابع: مجموعهای از چند خط کد که کار خاصی انجام میدهند، تابع میتواند مربوط به یک شیء از ماژولی باشد که به وسیلهی نقطه میتواند فراخوانی شود.
حلقه: بخشی از کد که میتواند به صورت تکراری یک یا چند بار اجرا شود.
کپسوله کردن: فرایند انتقال بخشی از کد به یک تابع را کپسوله کردن میگویند.
عمومیسازی: فرایند جایگزین کردن چیزی که به صورت خاص نیاز نیست(مانند یک عدد) با چیزی عمومی که مناسب برای استفاده باشد(مانند یک متغیر یا یک پارامتر عمومی).
آرگومان کیلدواژهای: آرگومانی که شامل نام آرگومان به عنوان کلیدواژه است.
رابط کاربری: توصیفی از تابع که مشخص میکن چگونه از آن تابع استفاده شود. مانند نام تابع، آرگومانهایی که میپذیرد، و مقداری که تابع برمیگرداند.
فاکتورگیری مجدد: فرایند اصلاح برنامهای که به درستی کار میکند تا رابط کاربری تابعها و کیفیت سایر قمستهای برنامه بهبود یابد.
نقشهی توسعه: فرایند طراحی و نوشتن یک برنامه.
رشتهمستند: رشتهای از کلمات که در بالاترین قسمت یک تابع قرار میگیرد و توضیحی در بارهی رابط کاربری آن تابع میدهد.
پیششرط: نیازمندیهای یک تابع، که باید توسط فراخوانندهی تابع فراهم شوند.
پسشرط: نیازمندیهایی که یک تابع باید قبل از اینکه اجرایش تمام شود، فراهم کند.
شکل 4.1 گلهای turtle
شکل 4.2 کیکهای turtle
4.12 تمرینها
تمرین 4.1 کد polygon.py را از این آدرس دانلود کنید.
- یک نمودار پشته (stack diagram) رسم کنید که حالت برنامه را هنگام اجرای (circle(bob,radius نمایش دهد. میتوانید به صورت دستی محسابات را انجام دهید یا در جاهایی از کد عبارت print قرار دهید.
- نسخهی تابع arc در بخش 4.7 خیلی دقیق نیست، زیرا تقریب خطی یک دایره، معمولا بیرون یک دایره است. در نتیجه turtle بعضی از پیکسلها را دور میاندازد. راه حل من، راهی را نشان میدهد که تاثیر این خطا را کاهش میدهد. کد را بخوانید ببینید آن را میفهمید یا خیر. اگر یک دیاگرام از آن رسم کنید، میتوانید بفهمید چگونه کار میکند.
تمرین 4.2 یک مجموعه تابع مناسب بنویسید که بتوانند گلهای شکل 4.1 را رسم کنند.
راه حل: http://greenteapress.com/thinkpython2/code/polygon.py
تمرین 4.3 یک مجموعه تابع بنویسید که بتوانند شکلهای شکل 4.2 را رسم کنند.
تمرین 4.4 حروف الفبا میتوانند به وسیلهی تعدادی المان، مانند خطهای افقی و عمودی و کمان، ساخته شوند.
حروف الفبا را به گونهای طراحی کنید تا بتوانید آنها را با کمترین تعداد المانهای پایه رسم کنید.
سپس یک مجموعه توابعی بنویسید که این حروف الفبا را رسم کنند.
شما باید برای هر حرف الفبا یک تابع با نام draw_a و draw_b و.. بنویسید. سپس این تابعها را در یک فایل به نام letters.py قرار دهید.
میتوانید یک "نویسندهی turtle" برای تست کد خود از آدرس http://greenteapress.com/thinkpython2/code/typewriter.py
دانلود کنید.\